local function calculateCircleIntersection(p1, p2, r)
    local x = p2.x - p1.x
    local z = p2.z - p1.z
    if 4 * r ^ 2 * x ^ 2 * z ^ 2 - x ^ 4 * z ^ 2 + 4 * r ^ 2 * z ^ 4 - 2 * x ^ 2 * z ^ 4 - z ^ 6 <= 0 then return end
    local sqrt = math.sqrt(-z ^ 2 * (x ^ 2 + z ^ 2)(-4 * r ^ 2 + x ^ 2 + z ^ 2))
    local I1 = {
        p1.x + 1 / 2 * (x - sqrt / (x ^ 2 + z ^ 2)),
        p1.z + (z ^ 2 + (x * sqrt) / (x ^ 2 + z ^ 2)) / (2 * z)
    }
    local I2 = {
        p1.x + 1 / 2 * (x + sqrt / (x ^ 2 + z ^ 2)),
        p1.z + z / 2 - (x * sqrt / (2 * x ^ 2 * z + 2 * z ^ 3))
    }
    return { x = I1, z = I2 }
end

local function findLineThroughPoints(p1, p2)
    if p1.x == p2.x then p1.x = p1.x + 0.0000001 end
    local m = (p2.z - p1.z) / (p2.x - p1.x)
    return { m = m, b = p1.z - m * p1.x }
end

local function findLineIntersection(f1, f2)
    if f1.m == f2.m then return end
    local x = (-f1.b + f2.b) / (f1.m - f1.m)
    return { x = x, z = f1.m * x + f1.b }
end
function findTarget(range)
    local bestPointScore, bestPoint = 0, nil
    local heros = {}
    for i = 1, GetHeroCount(), 1 do
        local hero = GetHero(i)
        if hero and hero.team == TEAM_ENEMY and hero.visible and not hero.dead then
            table.insert(heros, hero)
        end
    end
    local function testPoint(x, r)
        if math.sqrt((player.x - x.x) ^ 2 + (player.z - x.z) ^ 2) > r then return 0 end
        local ctr = 0
        for i, object in ipairs(heros) do
            if object~=x then if math.sqrt((object.x - x.x) ^ 2 + (object.z - x.z) ^ 2) < r then ctr = ctr + 1 end end
        end
        if bestPointScore < ctr then
            bestPoint = x;
            bestPointScore = ctr;
        end
        return ctr;
    end
    local findLines = {}
    for i = 1, #heros - 1, 1 do
        local c1 = heros[i]
        testPoint(c1, range)
        for j = i + 1, #heros, 1 do
            local c2 = heros[j]
            local Is = calculateCircleIntersection(c1, c2, range)
            if Is then
                table.insert(findLines, Is)
                testPoint({ x = 0.5 * (c1.x + c2.x), z = 0.5 * (c1.z + c2.z) }, range)
            end
        end
    end
    for i = 1, #findLines - 1, 1 do
        local l1 = findLines[i]
        for j = i + 1, #findLines, 1 do
            local l2 = findLines[j]
            local Int = findLineIntersection(l1, l2);
            if Int then testPoint(Int, range) end
        end
    end
    return bestPoint
end

